package effectiveJava.Reference;

import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository;
import org.junit.Test;

import java.lang.ref.WeakReference;
import java.util.*;

/**
 * Created by dycong on 2017/7/23.
 */
public class Weak {
    /**
     * 弱引用使用 get() 方法取得对象的强引用从而访问目标对象。
     * 一旦系统内存回收，无论内存是否紧张，弱引用指向的对象都会被回收。
     * 弱引用也可以避免 Heap 内存不足所导致的异常。
     *
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        WeakReference<ObjectForTest> bean = new WeakReference<ObjectForTest>(new ObjectForTest());
        ObjectForTest reference = bean.get();
        reference.setName("test");
        reference.setWeight(2);
        System.out.println(bean.get());
        reference = null;       //todo 此处不设为null则会转为强引用
        System.out.println(bean.get());
        System.gc();
        System.runFinalization();
        Thread.sleep(1000l);
        System.out.println(bean.get());
    }

    // TODO: 2017/7/23 如果想使用这些相对强引用来说较弱的引用来进行对象操作的时候，就必须保证没有强引用指向被操作对象。否则将会被视为强引用指向，不会具有任何的弱引用的特性。
    @Test
    public void test1() {
//        List<effectiveJava.Reference<ObjectForTest>> ofts = new ArrayList<>();
        List<Object> ofts = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            ofts.add(new WeakReference<ObjectForTest>(new ObjectForTest("TEST", 100)));
        }

        ofts.stream().forEach(o -> System.out.println(((WeakReference)o).get()));
        System.gc();
        System.out.println("--------------------");
        System.out.println(ofts.size());        //todo 放入list(List<effectiveJava.Reference<ObjectForTest>> /  List<Object>)的弱引用仍然会被回收，当有直接声明的变量指向弱引用时转为强引用
        ofts.stream().forEach(o -> System.out.println(((WeakReference)o).get()));
    }

    @Test
    public void test2(){
        WeakHashMap<String,String>weakHashMap=new WeakHashMap<>();
        for (int i=0;i<100;weakHashMap.put(""+i,i+""),i++);
        System.out.println(weakHashMap);
        System.gc();
        System.out.println(weakHashMap);
        NonCachingClassLoaderRepository.SoftHashMap softHashMap=new NonCachingClassLoaderRepository.SoftHashMap(new HashMap());
        softHashMap.put("1","2");
        System.out.println(softHashMap.get("1"));
    }


}
